<script>
import ButtonList from '@/components/ButtonList'
import TableButtonList from '@/components/TableButtonList'
import WrapTable from '@/components/WrapTable'
import store from './store'
import FormPanel from '@/components/FormPanel'
import SearchForm from '@/components/SearchForm'
import emitter from '@cci/cui/lib/mixins/emitter'
import { commonMixin } from '@/mixins/common'
import { deepClone } from '@/utils'
import { funType } from '@/utils/store/jsonCode.js'

export default {
  mixins: [store, emitter, commonMixin],
  data() {
    return {
      labelWidth: '80px',
      tableOptWidth: '100',
      selectedList: [],
      formIsShow: true,
      dialogType: '',
      idKey: 'funId',
      delIdKey: 'funId',
      delListIdKey: 'funIds',
      tableDefaultSort: { prop: 'funId', order: 'descending' },
      tableSelectionCol: true,
      tableIndexCol: true,
      pagination: true,
      autoLoad: true,
      showInputFlag: false,
      inputPlaceholder: '',
      searchInput: '',
      btnListWidthPercent: 18,
      btnListWidthOffset: 0,
      searchInputWidthPercent: 6,
      searchInputWidthOffset: 0,
      haveTool: true,

      columns: [
        {
          prop: 'funId',
          label: '功能编号',
          sortable: true,
          width: '240',
          'header-align': 'center'
        },
        {
          prop: 'funName',
          label: '功能名称',
          width: '240',
          'header-align': 'center'
        },
        {
          prop: 'location',
          label: '地址',
          width: '220',
          'header-align': 'center'
        },
        {
          prop: 'pid',
          label: '父功能',
          width: '160',
          'header-align': 'center'
        },
        {
          prop: 'orderNo',
          label: '排序号',
          width: '64',
          'header-align': 'center',
          align: 'right'
        },
        {
          prop: 'funType',
          label: '功能类型',
          width: '160',
          formatter: (row, column, cellValue) => funType(cellValue),
          'header-align': 'center'
        },
        {
          prop: 'logFlag',
          label: '是否记日志',
          width: '100',
          formatter: (row, column, cellValue) => (cellValue ? '是' : '否'),
          'header-align': 'center',
          align: 'center'
        },
        { prop: 'icon', label: '图标', width: '80', 'header-align': 'center' },
        {
          prop: 'version',
          label: '版本',
          width: '64',
          'header-align': 'center',
          align: 'right'
        }
      ],
      searchFields: [
        {
          label: '功能编号',
          prop: 'funId',
          placeholder: '长度在 3 到 5 个字符',
          anchor: 8
        },
        {
          label: '功能名称',
          prop: 'funName',
          placeholder: '输入功能名称',
          anchor: 8
        },
        {
          label: '功能类型',
          prop: 'funType',
          placeholder: '请选择功能类型',
          xType: 'SelectCode.FUN_TYPE',
          anchor: 8
        },
        {
          label: '连接地址',
          prop: 'location',
          placeholder: '输入连接地址',
          anchor: 8
        }
      ],
      searchModel: {
        funId: '',
        funName: '',
        location: '',
        funType: ''
      },
      searchBtnList: [
        {
          label: '查询',
          methods: 'handleSearch',
          icon: 'el-icon-search',
          type: 'primary',
          disabled: false
        },
        {
          label: '重置',
          methods: 'handleSearchReset',
          icon: 'el-icon-refresh',
          type: 'warning',
          disabled: false
        },
        {
          label: '导出',
          methods: '',
          icon: 'el-icon-refresh',
          type: 'info',
          disabled: false
        }
      ],
      toolPanelBtnList: [
        {
          label: '新增',
          methods: 'handleAdd',
          icon: 'el-icon-circle-plus-outline',
          type: 'primary',
          disabled: false
        },
        {
          label: '删除',
          methods: 'handleDelGroup',
          icon: 'el-icon-delete',
          type: 'danger',
          disabled: false
        },
        {
          label: '导出',
          methods: '',
          icon: 'el-icon-refresh',
          type: 'info',
          disabled: false
        }
      ],
      tableRowBtnList: [
        {
          label: '编辑',
          methods: 'handleEdit',
          icon: 'el-icon-edit-outline',
          type: 'primary',
          key: 'edit',
          align: 'top-start',
          disabled: false
        },
        {
          label: '删除',
          methods: 'handleDelete',
          icon: 'el-icon-delete',
          type: 'danger',
          key: 'delete',
          align: 'top-start',
          disabled: false
        }
      ],
      formPanel: {
        add: {
          model: {
            funId: '',
            funName: '',
            location: '',
            pid: '',
            orderNo: '',
            funType: '',
            logFlag: 1,
            icon: '',
            version: ''
          },
          fields: [
            {
              label: '功能编号',
              prop: 'funId',
              placeholder: '长度在 3 到 5 个字符',
              anchor: 24,
              ref: 'funId',
              focus: true
            },
            {
              label: '功能名称',
              prop: 'funName',
              placeholder: '输入功能名称',
              anchor: 24
            },
            {
              label: '连接地址',
              prop: 'location',
              placeholder: '输入连接地址',
              anchor: 24
            },
            {
              label: '父功能',
              prop: 'pid',
              placeholder: '请选择父功能',
              xType: 'SelectTree.SYS_FUN',
              anchor: 24
            },
            {
              label: '排序号',
              prop: 'orderNo',
              placeholder: '输入排序号',
              anchor: 24
            },
            {
              label: '功能类型',
              prop: 'funType',
              placeholder: '请选择功能类型',
              xType: 'SelectCode.FUN_TYPE',
              anchor: 24
            },
            {
              label: '记日志',
              prop: 'logFlag',
              xType: 'switch',
              anchor: 24,
              'active-value': 1,
              'inactive-value': 0
            },
            { label: '图标', prop: 'icon', anchor: 24 },
            { label: '版本', prop: 'version', anchor: 24 }
          ],
          rules: {
            funId: [
              { required: true, message: '请输入功能编号', trigger: 'blur' }
            ],
            funName: [
              { required: true, message: '请输入功能名称', trigger: 'blur' }
            ],
            funType: [
              { required: true, message: '请选择功能类型', trigger: 'blur' }
            ]
          },
          title: '新增信息',
          type: 'ADD',
          ref: 'addForm',
          submitBtnList: [
            {
              label: '保存并新增',
              methods: 'handleSubmitAndAdd',
              icon: 'el-icon-circle-check-outline',
              type: 'primary',
              disabled: false
            },
            {
              label: '保存',
              methods: 'handleAddSubmit',
              icon: 'el-icon-circle-check-outline',
              type: 'primary',
              disabled: false
            },
            {
              label: '取消',
              methods: 'handleCancel',
              icon: 'el-icon-circle-close-outline',
              disabled: false
            }
          ]
        },
        edit: {
          model: {
            funId: '',
            funName: '',
            location: '',
            pid: null,
            orderNo: '',
            funType: '',
            logFlag: '',
            icon: '',
            version: ''
          },
          fields: [
            {
              label: '功能编号',
              prop: 'funId',
              placeholder: '长度在 3 到 5 个字符',
              anchor: 24,
              disabled: true
            },
            {
              label: '功能名称',
              prop: 'funName',
              placeholder: '输入功能名称',
              anchor: 24,
              focus: true
            },
            {
              label: '连接地址',
              prop: 'location',
              placeholder: '输入连接地址',
              anchor: 24
            },
            {
              label: '父功能',
              prop: 'pid',
              placeholder: '请选择父功能',
              xType: 'SelectTree.SYS_FUN',
              anchor: 24
            },
            {
              label: '排序号',
              prop: 'orderNo',
              placeholder: '输入排序号',
              anchor: 24
            },
            {
              label: '功能类型',
              prop: 'funType',
              placeholder: '请选择功能类型',
              xType: 'SelectCode.FUN_TYPE',
              anchor: 24
            },
            {
              label: '记日志',
              prop: 'logFlag',
              xType: 'switch',
              anchor: 24,
              'active-value': 1,
              'inactive-value': 0
            },
            { label: '图标', prop: 'icon', anchor: 24 },
            { label: '版本', prop: 'version', anchor: 24 }
          ],
          rules: {
            funId: [
              { required: true, message: '请输入功能编号', trigger: 'blur' }
            ],
            funName: [
              { required: true, message: '请输入功能名称', trigger: 'blur' }
            ],
            funType: [
              { required: true, message: '请选择功能类型', trigger: 'blur' }
            ]
          },
          title: '编辑信息',
          type: 'EDIT',
          ref: 'editForm',
          submitBtnList: [
            {
              label: '保存',
              methods: 'handleEditSubmit',
              icon: 'el-icon-circle-check-outline',
              type: 'primary',
              disabled: false
            },
            {
              label: '取消',
              methods: 'handleCancel',
              icon: 'el-icon-circle-close-outline',
              disabled: false
            }
          ]
        },
        look: {
          model: {
            funId: '',
            funName: '',
            location: '',
            pid: '',
            orderNo: '',
            funType: '',
            logFlag: '',
            icon: '',
            version: ''
          },
          fields: [
            {
              label: '功能编号',
              prop: 'funId',
              placeholder: '长度在 3 到 5 个字符',
              anchor: 24,
              disabled: true
            },
            {
              label: '功能名称',
              prop: 'funName',
              placeholder: '输入功能名称',
              anchor: 24,
              disabled: true
            },
            {
              label: '连接地址',
              prop: 'location',
              placeholder: '输入连接地址',
              anchor: 24,
              disabled: true
            },
            {
              label: '父功能',
              prop: 'pid',
              placeholder: '请选择父功能',
              xType: 'SelectTree.SYS_FUN',
              anchor: 24,
              disabled: true
            },
            {
              label: '排序号',
              prop: 'orderNo',
              placeholder: '输入排序号',
              anchor: 24,
              disabled: true
            },
            {
              label: '功能类型',
              prop: 'funType',
              placeholder: '请选择功能类型',
              xType: 'SelectCode.FUN_TYPE',
              anchor: 24,
              disabled: true
            },
            {
              label: '记日志',
              prop: 'logFlag',
              xType: 'switch',
              anchor: 24,
              'active-value': 1,
              'inactive-value': 0,
              disabled: true
            },
            { label: '图标', prop: 'icon', anchor: 24 },
            { label: '版本', prop: 'version', anchor: 24 }
          ],
          rules: {},
          title: '查看信息',
          type: 'LOOK',
          ref: 'lookForm',
          submitBtnList: [
            {
              label: '保存',
              methods: '',
              icon: 'el-icon-circle-check-outline',
              type: 'primary',
              disabled: true
            },
            {
              label: '取消',
              methods: 'handleCancel',
              icon: 'el-icon-circle-close-outline',
              disabled: false
            }
          ]
        }
      }
    }
  },
  computed: {
    data() {
      return this.store.data
    },
    total() {
      return this.store.total
    }
  },
  components: {
    FormPanel,
    SearchForm,
    WrapTable,
    ButtonList,
    TableButtonList
  },
  mounted() {
    window.eventBus.$on('breadcrumb-click', () => {
      this.dialogType = ''
      this.formIsShow = true
    })
  },
  methods: {
    /**
     * 定义表格 WrapTable 组件内部使用的 发送分页请求数据的 方法
     */
    getData({ page, limit }) {
      this.store.read({ start: page, limit: limit })
    },
    /**
     * 点击页面顶部表单 重置按钮 触发
     * - 模板中该方法会将顶部表单内容重置
     */
    handleSearchReset() {
      this.$refs.searchForm.onReset()
    },
    /**
     * 点击页面顶部表单 查询按钮 触发
     * - 模板中该方法会执行：
     *   -- 根据页面顶部表单填入内容，处理发送表格分页请求参数
     *   -- 调用表格 WrapTable 组件 load() 方法，发送分页数据请求，渲染 WrapTable 组件
     */
    handleSearch(data) {
      if (data) {
        for (const k in data) {
          if (data.hasOwnProperty(k)) {
            this.store._searchParams['q_' + k] = data[k]
          }
        }
        this.$refs.table.load(1, this.store.limit)
      }
    },
    /**
     * 点击页面表格顶部 新增按钮 触发
     * - 模板中该方法会执行：
     *   -- 切换 新增表格项信息表单 面板
     *   -- 将 新增表格项信息表单 清空
     */
    handleAdd() {
      this.formIsShow = false
      this.dialogType = this.formPanel.add.type
      this.$nextTick(() => {
        this.$refs.addForm && this.$refs.addForm.resetFields()
      })
    },
    /**
     * 点击页面表格顶部 删除按钮 触发
     * - 模板中该方法会执行：
     *    -- 如果没有勾选的表格项，提示没有要删除的数据，直接返回
     *    -- 否则将勾选的表格项的 唯一标识（如 id）存放入数组
     *    -- 提示操作不能回退，取消则返回，否则将数组作为数据向后台发送删除请求：
     *       ---- 删除请求发送成功，则提示删除成功信息
     *            删除请求发送失败则提示失败信息
     */
    handleDelGroup() {
      if (this.selectedList.length === 0) {
        this.$message({
          type: 'info',
          message: '没有要删除的数据'
        })
        return Promise.reject(new Error('没有要删除的数据'))
      }
      const funIds = this.selectedList
        .map(item => {
          return item[this.delIdKey]
        })
        .join(',')
      return this.$confirm(
        '此操作不能回退，确认要删除您选中的数据么?',
        '提示',
        {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning'
        }
      )
        .then(() => {
          const params = {}
          params[this.delListIdKey] = funIds
          return this.delList(params)
        })
        .then(({ success }) => {
          if (success) {
            this.$refs.table.load(1)
            this.$refs.table.clearSelection()
            this.$message({
              type: 'success',
              message: '删除成功!'
            })
          } else {
            this.$message({
              type: 'error',
              message: '删除失败!'
            })
          }
        })
        .catch(error => {
          this.$message({
            type: 'info',
            message: error === 'cancel' ? '已取消删除' : error
          })
          return Promise.reject(error)
        })
    },
    /**
     * 响应页面表格 WrapTable 组件 双击表格项 时派发的 row-dblclick 事件回调
     *  - 当双击 WrapTable 组件 表格项, 会派发 row-dblclick 事件
     *  - 模板中该方法会执行：
     *    -- 切换 查看表格项信息表单 面板
     *    -- 将 查看表格项信息表单 清空
     *    -- 将之前双击的表格项数据 覆写 查看表格项信息表单绑定数据 model
     */
    handleCurrentChange(row) {
      this.$refs.lookForm && this.$refs.lookForm.resetFields()
      this.dialogType = this.formPanel.look.type
      this.formIsShow = false
      Object.keys(row).forEach(key => {
        this.$set(this.formPanel.look.model, key, row[key])
      })
    },
    /**
     * 点击页面表格中表格项最后一列 操作列中 编辑按钮 触发
     * - 模板中该方法会执行：
     *   -- 根据表格项数据中 唯一标识（如 id）向后台发起请求，获取该表格项的最新数据
     *   -- 使用初始数据 覆写 model， 再将最新的表格项数据 覆写 编辑表格项信息表单绑定数据 model
     *   -- 打开 编辑表格项信息表单 弹窗
     */
    handleEdit(row) {
      const params = {}
      params[this.idKey] = row[this.idKey]
      return this.check(params)
        .then(({ success, message, data }) => {
          if (success) {
            Object.assign(this.formPanel.edit.model, this.editModelInitialData)
            for (const key in this.formPanel.edit.model) {
              this.$set(this.formPanel.edit.model, key, data[key])
            }
            this.dialogType = this.formPanel.edit.type
            return data
          } else {
            this.$message({
              type: 'error',
              message
            })
            throw new Error(message)
          }
        })
        .catch(err => {
          console.log(err)
          return Promise.reject(err)
        })
    },
    /**
     * 点击页面表格中表格项最后一列 操作列中 删除按钮 触发
     * - 模板中该方法会执行：
     *    -- 提示是否要删除数据，否就返回
     *    -- 是则根据表格项数据中 唯一标识（如 id）向后台发起删除请求：
     *       ---- 删除请求发送成功，则提示删除成功信息
     *            删除请求发送失败则提示失败信息
     */
    handleDelete(row) {
      return this.$confirm(
        '此操作不能回退，确认要删除您选中的数据么?',
        '提示',
        {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning'
        }
      )
        .then(() => {
          const params = {}
          params[this.delIdKey] = row[this.delIdKey]
          return this.del(params)
        })
        .then(({ success, message }) => {
          this.$message({
            type: success ? 'success' : 'error',
            message: message
          })
          if (success) {
            this.$refs.table.load(1)
          }
          setTimeout(() => {
            document.activeElement.blur()
          }, 300)
        })
        .catch(error => {
          setTimeout(() => {
            document.activeElement.blur()
          }, 300)
          this.$message({
            type: 'info',
            message: error === 'cancel' ? '已取消删除' : error
          })
          return Promise.reject(error)
        })
    },
    /**
     * 响应页面表格 WrapTable 组件 表格项勾选框 勾选时派发的 selection-change 事件回调
     *  - 当点击 WrapTable 组件 表格项的勾选框, 会派发 selection-change 事件
     *  - 模板中该方法拿到表格中已经勾选数据，并赋给 selectedList
     */
    handleSelectionChange(val) {
      this.selectedList = val
    },
    /**
     * 点击新增表格项信息表单 面板底部 保存并新增按钮 触发
     * - 模板中该方法会执行：
     *    -- 验证新增表格项信息表单内容
     *    -- 验证成功则将 新增表格项信息表单绑定数据 model 向后台发起新增请求：
     *       ---- 新增请求发送成功，则提示新增成功信息，调用 WrapTable 组件 load(1), 请求表格的分页数据；清空新增表格项信息表单
     *            新增请求发送失败则提示失败信息
     */
    handleSubmitAndAdd() {
      return this.$refs.addForm
        .validate()
        .then(() => {
          return this.add(this.formPanel.add.model)
        })
        .then(({ success, message }) => {
          this.$message({
            type: success ? 'success' : 'error',
            message: message
          })
          if (success) {
            this.$refs.addForm && this.$refs.addForm.resetFields()
            this.$nextTick(() => {
              this.$refs.table.load(1)
            })
          } else {
            throw new Error(message)
          }
        })
        .catch(err => {
          console.log(err)
          return Promise.reject(err)
        })
    },
    /**
     * 点击新增表格项信息表单 面板底部 保存按钮 触发
     * - 模板中该方法会执行：
     *    -- 验证新增表格项信息表单内容
     *    -- 验证成功则将 新增表格项信息表单绑定数据 model 向后台发起新增请求：
     *       ---- 新增请求发送成功，则提示新增成功信息，调用 WrapTable 组件 load(1), 请求表格的分页数据；切换显示表格 WrapTable 组件
     *            新增请求发送失败则提示失败信息
     */
    handleAddSubmit() {
      return this.$refs.addForm
        .validate()
        .then(() => {
          return this.add(this.formPanel.add.model)
        })
        .then(({ success, message }) => {
          this.$message({
            type: success ? 'success' : 'error',
            message: message
          })
          if (success) {
            this.dialogType = ''
            this.formIsShow = true
            this.$nextTick(() => {
              this.$refs.table.load(1)
            })
          } else {
            throw new Error(message)
          }
        })
        .catch(err => {
          console.log(err)
          return Promise.reject(err)
        })
    },
    /**
     * 点击编辑表格项信息表单 面板底部 保存按钮 触发
     * - 模板中该方法会执行：
     *    -- 验证 编辑表格项信息表单内容
     *    -- 验证成功则将 编辑表格项信息表单绑定数据 model 向后台发起更新请求：
     *       ---- 更新请求发送成功，则提示更新成功信息，调用 WrapTable 组件 load(), 请求表格的分页数据；切换到显示表格 WrapTable 组件
     *            更新请求发送失败则提示失败信息
     */
    handleEditSubmit() {
      return this.$refs.editForm
        .validate()
        .then(() => {
          return this.update(this.formPanel.edit.model)
        })
        .then(({ success, message }) => {
          this.$message({
            type: success ? 'success' : 'error',
            message: message
          })
          if (success) {
            this.dialogType = ''
            this.formIsShow = true
            this.$nextTick(() => {
              this.$refs.table.load()
            })
          } else {
            throw new Error(message)
          }
        })
        .catch(err => {
          console.log(err)
          return Promise.reject(err)
        })
    },
    /**
       * 响应页面表格右上方搜索输入框 键盘事件或icon点击事件
       *
       * handleInputClick(ev, val) {
        },
      */
    handleInputClick(_ev, _val) {},
    /**
     * 点击面板 右上角 x 按钮 / 右下角取消按钮 触发，切换显示表格 WrapTable 组件
     */
    handleCancel() {
      this.$refs.addForm && this.$refs.addForm.clearValidate()
      this.$refs.editForm && this.$refs.editForm.clearValidate()
      this.dialogType = ''
      this.formIsShow = true
    },
    renderOperateBtns(row) {
      return (
        <TableButtonList
          operateBtnList={this.tableRowBtnList}
          props-model={row}
        />
      )
    },
    /**
     * 渲染页面右侧 WrapTable 组件 jsx 写法
     */
    // eslint-disable-next-line
    renderWrapTable(h) {
      return (
        <WrapTable
          ref='table'
          v-show={this.formIsShow}
          getData={this.getData}
          total={this.total}
          data={this.data}
          fields={this.columns}
          selectionCol={this.tableSelectionCol}
          indexCol={this.tableIndexCol}
          pagination={this.pagination}
          autoLoad={this.autoLoad}
          tooltip-effect='dark'
          border
          stripe
          default-sort={this.tableDefaultSort}
          on-selection-change={this.handleSelectionChange}
          on-row-dblclick={this.handleCurrentChange}>
          {this.searchBtnList && this.searchBtnList.length > 0 ? (
            <SearchForm
              items={this.searchFields}
              props-model={this.searchModel}
              slot='searchPanel'
              ref='searchForm'>
              <ButtonList
                operateBtnList={this.searchBtnList}
                props-model={this.searchModel}></ButtonList>
            </SearchForm>
          ) : (
            ''
          )}

          <c-row slot='toolPanel' class='toolPanel'>
            {this.toolPanelBtnList && this.toolPanelBtnList.length ? (
              <c-col
                span={this.btnListWidthPercent}
                offset={this.btnListWidthOffset}>
                <ButtonList operateBtnList={this.toolPanelBtnList}></ButtonList>
              </c-col>
            ) : (
              ''
            )}
            <c-col
              span={this.searchInputWidthPercent}
              offset={this.searchInputWidthOffset}>
              {this.showInputFlag ? (
                <c-input
                  class='search-input'
                  placeholder={this.inputPlaceholder}
                  size='small'
                  v-model={this.searchInput}
                  on-input={event => {
                    this.searchInput = event
                  }}
                  nativeOnKeydown={ev => {
                    ev.keyCode === 13
                      ? this.handleInputClick(ev, this.searchInput)
                      : null
                  }}>
                  <i
                    slot='suffix'
                    class='el-input__icon el-icon-search'
                    on-click={ev =>
                      this.handleInputClick(ev, this.searchInput)
                    }></i>
                </c-input>
              ) : (
                ''
              )}
            </c-col>
          </c-row>

          {this.haveTool ? (
            <c-table-column
              label='操作'
              align='center'
              slot='toolbar'
              width={this.tableOptWidth}
              fixed='right'
              {...{
                scopedSlots: {
                  default: ({ row }) => this.renderOperateBtns(row)
                }
              }}
            />
          ) : (
            ''
          )}
        </WrapTable>
      )
    },
    /**
     * 渲染页面面板 FormPanel 组件 jsx 写法
     */
    // eslint-disable-next-line
    renderFormPanel(h) {
      return this._l(this.formPanel, item => {
        if (this.dialogType === item.type) {
          return (
            <FormPanel
              key={item.type}
              class='c-form-common'
              ref={item.ref}
              items={item.fields}
              inline={false}
              props-model={item.model}
              labelWidth={this.labelWidth}
              rules={item.rules}>
              <div class='el-form-header' slot='title'>
                {item.title}
              </div>
              <c-form-item class='submit-btn'>
                <ButtonList operateBtnList={item.submitBtnList} />
              </c-form-item>
            </FormPanel>
          )
        }
      })
    },
    /**
     * 渲染页面自定义模板 jsx 写法（这里使用空白节点占位）
     */
    // eslint-disable-next-line
    renderCustom(h) {
      return this._e()
    }
  },

  created() {
    // 对初始 this.formPanel.edit.model 进行深拷贝
    this.editModelInitialData = deepClone(this.formPanel.edit.model)
  },

  render(h) {
    return (
      <div class='table-container'>
        {this.renderWrapTable(h)}
        {this.renderFormPanel(h)}
        {this.renderCustom(h)}
      </div>
    )
  }
}
</script>
